//
//  Game.cpp
//  QuizMaster
//
//  Created by Jeppe Nielsen on 3/10/15.
//  Copyright (c) 2015 Jeppe Nielsen. All rights reserved.
//

#include "Game.hpp"
#include "TransformAnimatorSystem.hpp"
#include "AlignCategoriesSystem.hpp"
#include "SelectQuestionSystem.hpp"
#include "SelectQuestion.hpp"
#include "WaitForBuzz.hpp"
#include "AnswerQuestion.hpp"
#include "SoundSystem.hpp"
#include "ShowScores.hpp"
#include "SetupGame.hpp"
#include <sstream>

using namespace Nano;

#include <iostream>

void Game::Initialize() {
    
    //res 1440x900 + 1600x900 =  3040

    
    renderer = world.CreateSystem<RenderSystem>();
    gui = world.CreateFactory<Gui>();
    gui->Setup("images.png", "images.xml", Manager().Viewport(), Input);
    font = gui->CreateFont("font.fnt", "font");
    
    categoryFactory = world.CreateFactory<CategoryFactory>();
    categoryFactory->SetGui(gui, font);
    
    world.CreateSystem<TransformAnimatorSystem>();
    world.CreateSystem<AlignCategoriesSystem>()->boundingBox = BoundingBox(0, Vector3(-6,0,0));
    world.CreateSystem<SelectQuestionSystem>();
    world.CreateSystem<SoundSystem>();
    
    SetupCameras();
    
    AddState<SetupGame>("SetupGame");
    AddState<SelectQuestion>("SelectQuestion");
    AddState<WaitForBuzz>("WaitForBuzz");
    AddState<AnswerQuestion>("AnswerQuestion");
    AddState<ShowScores>("ShowScores");
    
    CurrentState = "SetupGame";
    
    downloader.DownloadFile("http://www.pocketgames.dk/quiz/DownloadQuestions.php").Completed += event_handler(this, &Game::DownloadQuestionsComplete);
    Input.ButtonDown += event_handler(this, &Game::ButtonDown);
    
    bigButtonManager.Initialize();
    bigButtonManager.ButtonDown += event_handler(this, &Game::BigButtonDown);
    bigButtonManager.ButtonUp += event_handler(this, &Game::BigButtonUp);
}

void Game::BigButtonDown(Nano::BigButtonEvent button) {
    static int counter = 0;

    if (button.Button == BigButtonButton::A) {
        counter++;
        std::cout << button.PlayerIndex << ": Big Button Down, counter:" << counter << std::endl;
    }
}

void Game::BigButtonUp(Nano::BigButtonEvent button) {
    static int counter = 0;

    if (button.Button == BigButtonButton::A) {
        counter++;
        std::cout << button.PlayerIndex << ": Big Button Up, counter:" << counter << std::endl;
    }
}

void Game::SetupCameras() {
    {
        GameObject* camera = world.CreateObject();
        camera->AddComponent<Camera>()->Viewport = Manager().Viewport();
        camera->AddComponent<Transform>()->Position = { 0, 0, 10 };
        camera->GetComponent<Camera>()->FieldOfView = 40;
        Box box = Manager().Viewport();
        box.right = 1440;
        camera->GetComponent<Camera>()->Viewport = box;
        camera->GetComponent<Camera>()->Mask = 1;
    }
    {
        GameObject* camera2 = world.CreateObject();
        camera2->AddComponent<Transform>()->Position = { 0, 0, 10 };
        camera2->AddComponent<Camera>()->FieldOfView = 40;
        Box box = Manager().Viewport();
        box.right = 3040;
        box.left = 1440;
        camera2->GetComponent<Camera>()->Viewport = box;
        camera2->GetComponent<Camera>()->Mask = 2;
    }
    
    Input.GamePad.ButtonDown += event_handler(this, &Game::GamePadButtonDown);
}

void Game::GamePadButtonDown(GamePadData data) {
    
}

void Game::ButtonDown(std::string button) {
    if (button == "\e") {
        CurrentState = "SetupGame";
    }
}

void Game::DownloadQuestionsComplete(Nano::DownloadedFile file) {
    std::string json;
    json.append((char*)file.data, file.size);
    
    questionDatabase.UpdateFromJSON(json);
    
    std::cout<< " Downloaded questions :"<<std::endl;
    for (auto it = questionDatabase.GetQuestions().begin(); it!=questionDatabase.GetQuestions().end(); ++it) {
        std::cout<< "id: " << it->second.id << ", question: "<< it->second.question << ", answer: " << it->second.answer<<", categoryID:"<<it->second.categoryID << std::endl;
    }
    
    downloader.DownloadFile("http://www.pocketgames.dk/quiz/DownloadCategories.php").Completed += event_handler(this, &Game::DownloadCategoriesComplete);
}

void Game::DownloadCategoriesComplete(Nano::DownloadedFile file) {
    std::string json;
    json.append((char*)file.data, file.size);
    
    categoryDatabase.UpdateFromJSON(json);
    
    std::cout<< " Downloaded categories :"<<std::endl;
    for (auto it = categoryDatabase.GetCategories().begin(); it!=categoryDatabase.GetCategories().end(); ++it) {
        std::cout<< "id: " << it->second.id << ", name: "<< it->second.name << std::endl;
    }
    categoryDatabase.UpdateFromQuestions(&questionDatabase);
    
    std::cout<< " Current categories :"<<std::endl;
    for (auto it = categoryDatabase.GetCategories().begin(); it!=categoryDatabase.GetCategories().end(); ++it) {
        std::cout<< it->second.name << std::endl;
        for (int i=0; i<it->second.questions.size(); i++) {
            Question* question = it->second.questions[i];
            std::cout<< "question: "<< question->question << ", answer: " << question->answer<<std::endl;
        }
        std::cout<<""<<std::endl;
    }
}

void Game::Update(float dt) {
    world.Update(dt);
    bigButtonManager.Update(dt);
}

void Game::Render() {
    renderer->Render();
}